package net.blank.ui.core
{
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	/**
	 * 排列
	 * @author blank
	 * 
	 */
	public class Arrange
	{
		/**
		 * 左对齐
		 */
		public static const LEFT:String = "left";
		/**
		 * 水平居中对齐
		 */
		public static const CENTER:String = "center";
		/**
		 * 右对齐
		 */
		public static const RIGHT:String = "rihgt";
		/**
		 * 上对齐
		 */
		public static const TOP:String = "top";
		/**
		 * 垂直居中对齐
		 */
		public static const MIDDLE:String = "middle";
		/**
		 * 下对齐
		 */
		public static const BOTTOM:String = "bottom";
		
		/**
		 * 不对齐
		 */
		public static const NO_ALIGN:String = "no_align";
		
		/**
		 * 计算指定集合中的所有对象按指定间距水平排列后的总宽度
		 * @param obj
		 * @param gap
		 * @return 
		 * 
		 */
		public static function totalWidth(objs:*,gap:Number):Number{
			var len:int = objs.length;
			var tw:Number = 0;
			
			var curChild:DisplayObject;
			for(var i:int = 0;i<len;i++ ){
				curChild = objs[i];
				
				tw += curChild.width + gap;
			}
			return tw - gap;
		}
		
		/**
		 * 计算指定集合中的所有对象按指定间距水平排列后的总高度
		 * @param objs
		 * @param gap
		 * @return 
		 * 
		 */
		public static function totalHeight(objs:*,gap:Number):Number{
			var len:int = objs.length;
			var th:Number = 0;
			
			var curChild:DisplayObject;
			for(var i:int = 0;i<len;i++ ){
				curChild = objs[i];
				
				th += curChild.height + gap;
			}
			return th - gap;
		}
		
		/**
		 * 获取指定集合中的所有对象的最大宽度和高度
		 * @param objs
		 * @return 
		 * 
		 */
		public static function getMaxSize(objs:*):Point{
			var len:int = objs.length;
			
			var maxW:Number=0,maxH:Number=0;
			var curChild:DisplayObject;
			for(var i:int = 0;i<len;i++ ){
				curChild = objs[i];
				
				if(curChild.width > maxW){
					maxW=curChild.width;
				}
				if(curChild.height > maxH){
					maxH=curChild.height;
				}
			}
			
			return new Point(maxW,maxH);
		}
		
		/**
		 * 水平排列指定集合中的所有对象
		 * @param objs 对象集合
		 * @param arrangeRect 排列区域
		 * @param gap 排列间隔
		 * @param horizontalAlign 水平对齐方式, Arrange 类中的静态常量("left", "center", "right")
		 * @param verticalAlign 垂直对齐方式, Arrange 类中的静态常量("top", "middle", "bottom","no_align")
		 * @param hExceedAlign 当排列后的对象列表的宽度超过排列区域的宽度时的水平对齐方式
		 * @return 排列后对象列表的宽度
		 * 
		 */
		public static function horizontalArrange(
			objs:*,
			arrangeRect:Rectangle,
			gap:int = 2,
			horizontalAlign:String = LEFT,
			verticalAlign:String = TOP,
			hExceedAlign:String = LEFT
		):Number{
			var len:int = objs.length;
			if(len > 0){
				var totalWidth:int = totalWidth(objs,gap);
				
				if(totalWidth >= arrangeRect.width){
					horizontalAlign=hExceedAlign;
				}
				
				var curChild:DisplayObject;
				var leftChild:DisplayObject;
				for(var i:int = 0;i<len;i++ ){
					curChild = objs[i];
					
					switch(verticalAlign){
						default:
						case TOP:
							curChild.y = arrangeRect.y;
							break;
						case MIDDLE:
							curChild.y = arrangeRect.y + (arrangeRect.height - curChild.height) >> 1;
							break;
						case BOTTOM:
							curChild.y = arrangeRect.y + arrangeRect.height - curChild.height;
							break;
						case NO_ALIGN:
							break;
					}
					
					if(leftChild){
						curChild.x = leftChild.x + leftChild.width + gap;
					}else{
						switch(horizontalAlign){
							default:
							case LEFT:
								curChild.x = arrangeRect.x;
								break;
							case CENTER:
								curChild.x = arrangeRect.x + (arrangeRect.width - totalWidth) >> 1;
								break;
							case RIGHT:
								curChild.x = arrangeRect.x + arrangeRect.width - totalWidth;
								break;
							case NO_ALIGN:
								break;
						}
					}
					leftChild = curChild;
				}
				return totalWidth;
			}
			return 0;
		}
		
		/**
		 * 垂直排列指定集合中的所有对象
		 * @param objs 对象集合
		 * @param arrangeRect 排列区域
		 * @param gap 排列间隔
		 * @param horizontalAlign 水平对齐方式, Arrange 类中的静态常量("left", "center", "right")
		 * @param verticalAlign 垂直对齐方式, Arrange 类中的静态常量("top", "middle", "bottom")
		 * @param vExceedAlign 当排列后的对象列表的高度超过排列区域的高度时的垂直对齐方式
		 * @return 排列后对象列表的高度
		 * 
		 */
		public static function verticalArrange(
			objs:*,
			arrangeRect:Rectangle,
			gap:int = 2,
			horizontalAlign:String = LEFT,
			verticalAlign:String = TOP,
			vExceedAlign:String = TOP
		):Number{
			var len:int = objs.length;
			if(len > 0){
				var totalHeight:int = totalHeight(objs,gap);
				
				if(totalHeight >= arrangeRect.height){
					verticalAlign=vExceedAlign;
				}
				
				var curChild:DisplayObject;
				var upChild:DisplayObject;
				for(var i:int = 0;i<len;i++){
					curChild = objs[i];
					
					switch(horizontalAlign){
						default:
						case LEFT:
							curChild.x = arrangeRect.x;
							break;
						case CENTER:
							curChild.x = arrangeRect.x + (arrangeRect.width-curChild.width) >> 1;
							break;
						case RIGHT:
							curChild.x = arrangeRect.x + arrangeRect.width-curChild.width;
							break;
						case NO_ALIGN:
							break;
					}
					
					if(!upChild){
						switch(verticalAlign){
							default:
							case TOP:
								curChild.y = arrangeRect.y;
								break;
							case MIDDLE:
								curChild.y = arrangeRect.y + (arrangeRect.height-totalHeight) >> 1;
								break;
							case BOTTOM:
								curChild.y = arrangeRect.y + arrangeRect.height-totalHeight;
								break;
							case NO_ALIGN:
								break;
						}
					}else{
						curChild.y = upChild.y+upChild.height+gap;
					}
					upChild = curChild;
				}
				return totalHeight;
			}
			return 0;
		}
		
		/**
		 * 瓦片式排列指定集合中的所有对象
		 * @param objs 对象集合
		 * @param arrangeRect 排列区域
		 * @param cellSize 单元格的大小
		 * @param numCols 列数
		 * @param hGap 水平排列间隔
		 * @param vGap 垂直排列间隔
		 * @param horizontalAlign 水平对齐方式, Arrange 类中的静态常量("left", "center", "right")
		 * @param verticalAlign 垂直对齐方式, Arrange 类中的静态常量("top", "middle", "bottom")
		 * @param innerHorizontalAlign 对象在所属网格内的水平对象方式, Arrange 类中的静态常量("left", "center", "right")
		 * @param innerVerticalAlign 对象在所属网格内的垂直对象方式, Arrange 类中的静态常量("top", "middle", "bottom")
		 * @param hExceedAlign 当排列后的对象列表的宽度超过排列区域的宽度时的水平对齐方式
		 * @param vExceedAlign 当排列后的对象列表的高度超过排列区域的高度时的垂直对齐方式
		 * @return 排列后对象列表的大小
		 * 
		 */
		public static function tileArrang(
			objs:*,
			arrangeRect:Rectangle,
			cellSize:Point,
			numCols:int,
			hGap:int = 2,
			vGap:int = 2,
			horizontalAlign:String = LEFT,
			verticalAlign:String = TOP,
			innerHorizontalAlign:String = CENTER,
			innerVerticalAlign:String = MIDDLE,
			hExceedAlign:String = LEFT,
			vExceedAlign:String = TOP
		):Point{
			var len:int = objs.length;
			if(len > 0){
				var cellWidth:int=cellSize.x + hGap;
				var cellHeight:int=cellSize.y + vGap;
				
				var numRows:int=Math.ceil(len / numCols);
				
				var totalWidth:int = numCols * cellWidth - hGap;
				var totalHeight:int = numRows * cellHeight - vGap;
				
				if(totalWidth >= arrangeRect.width){
					horizontalAlign=hExceedAlign;
				}
				if(totalHeight >= arrangeRect.height){
					verticalAlign=vExceedAlign;
				}
				
				/**排列区域的开始位置*/
				var hx:int, vy:int;
				switch(horizontalAlign){
					default:
					case LEFT:
						hx = arrangeRect.x;
						break;
					case CENTER:
						hx = arrangeRect.x + ((arrangeRect.width-totalWidth) >> 1);
						break;
					case RIGHT:
						hx = arrangeRect.x + arrangeRect.width-totalWidth;
						break;
				}
				switch(verticalAlign){
					default:
					case TOP:
						vy = arrangeRect.y;
						break;
					case MIDDLE:
						vy = arrangeRect.y + ((arrangeRect.height-totalHeight) >> 1);
						break;
					case BOTTOM:
						vy = arrangeRect.y + arrangeRect.height-totalHeight;
						break;
				}
				
				var index:int=0;
				var curChild:DisplayObject;
				for(var i:int=0;i<numRows;i++){
					for(var j:int=0;j<numCols;j++){
						if(index < len){
							curChild=objs[index++];
							
							switch(innerHorizontalAlign){
								default:
								case LEFT:
									curChild.x = hx + j * cellWidth;
									break;
								case CENTER:
									curChild.x = hx + j * cellWidth + ((cellWidth-curChild.width) >> 1);
									break;
								case RIGHT:
									curChild.x = hx + j * cellWidth + (cellWidth-curChild.width);
									break;
							}
							switch(innerVerticalAlign){
								default:
								case TOP:
									curChild.y = vy + i * cellHeight;
									break;
								case MIDDLE:
									curChild.y = vy + i * cellHeight + ((cellHeight-curChild.height) >> 1);
									break;
								case BOTTOM:
									curChild.y = vy + i * cellHeight + (cellHeight-curChild.height);
									break;
							}
						}else{
							return new Point(totalWidth,totalHeight);
						}
					}
				}
				return new Point(totalWidth,totalHeight);
			}
			return new Point(0,0);
		}
		
		/**
		 * 自动以瓦片式排列指定集合中的所有对象(根据所有对象中最大宽度和最大高度划分网格)
		 * @param objs 对象集合
		 * @param arrangeRect 排列区域
		 * @param hGap 水平排列间隔
		 * @param vGap 垂直排列间隔
		 * @param horizontalAlign 水平对齐方式, Arrange 类中的静态常量("left", "center", "right")
		 * @param verticalAlign 垂直对齐方式, Arrange 类中的静态常量("top", "middle", "bottom")
		 * @param innerHorizontalAlign 对象在所属网格内的水平对象方式, Arrange 类中的静态常量("left", "center", "right")
		 * @param innerVerticalAlign 对象在所属网格内的垂直对象方式, Arrange 类中的静态常量("top", "middle", "bottom")
		 * @param vExceedAlign 当排列后的对象列表的高度超过排列区域的高度时的垂直对齐方式
		 * @return 排列后对象列表的大小
		 */
		public static function autoTileArrange(
			objs:*,
			arrangeRect:Rectangle,
			hGap:int = 2,
			vGap:int = 2,
			horizontalAlign:String = LEFT,
			verticalAlign:String = TOP,
			innerHorizontalAlign:String = CENTER,
			innerVerticalAlign:String = MIDDLE,
			vExceedAlign:String = TOP
		):Point{
			var len:int = objs.length;
			if(len > 0){
				var cellSize:Point=getMaxSize(objs);
				
				var cellWidth:int=cellSize.x + hGap;
				var cellHeight:int=cellSize.y + vGap;
				
				var numCols:int=arrangeRect.width / cellWidth;
				if(numCols * cellWidth + cellSize.x <= arrangeRect.width){
					numCols++;
				}
				if(numCols > len){
					numCols=len;
				}
				
				return tileArrang(
					objs,
					arrangeRect,
					cellSize,
					numCols,
					hGap,vGap,
					horizontalAlign,verticalAlign,innerHorizontalAlign,
					innerVerticalAlign,horizontalAlign,
					vExceedAlign
				);
			}
			return new Point(0,0);
		}
		
		/**
		 * 对齐
		 * @param objs 对象列表
		 * @param alignRect 对齐区域
		 * @param horizentalAlign 水平对齐方式
		 * @param verticalAlign 垂直对齐方式
		 * 
		 */
		public static function align(objs:*,alignRect:Rectangle,horizentalAlign:String=null,verticalAlign:String=null):void{
			var len:uint=objs.length;
			if(len > 0){
				var obj:*;
				for(var i:uint=0;i<len;i++){
					obj=objs[i];
					switch(horizentalAlign){
						case LEFT:
							obj.x=alignRect.x;
							break;
						case RIGHT:
							obj.x=alignRect.right-obj.width;
							break;
						case CENTER:
							obj.x=alignRect.x+((alignRect.width-obj.width) >> 1);
							break;
					}
					switch(verticalAlign){
						case TOP:
							obj.y=alignRect.y;
							break;
						case BOTTOM:
							obj.y=alignRect.bottom-obj.height;
							break;
						case MIDDLE:
							obj.y=alignRect.y+((alignRect.height-obj.height) >> 1);
							break;
					}
				}
			}
		}
		
		/**
		 * 获取包括所有对象的最小矩形
		 * @param objs 对象列表
		 * @return 
		 * 
		 */
		public static function getMinRect(objs:*):Rectangle{
			if(objs && objs.length > 0){
				var minX:Number=int.MAX_VALUE, minY:Number=int.MAX_VALUE, maxRight:Number=int.MIN_VALUE, maxBottom:Number=int.MIN_VALUE;
				for each(var target:* in objs){
					if(target.x < minX){
						minX=target.x;
					}
					if(target.y < minY){
						minY=target.y;
					}
					if(target.x + target.width > maxRight){
						maxRight=target.x + target.width;
					}
					if(target.y + target.height > maxBottom){
						maxBottom=target.y + target.height;
					}
				}
				return new Rectangle(minX,minY,maxRight-minX,maxBottom-minY);
			}
			return null;
		}
	}
}